package com.oraro.paygatewaybiz.channel.wxpay.serviceImpl;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.oraro.common.result.Result;
import com.oraro.middleservice.logger.starter.supports.BizLoggerHelper;
import com.oraro.paygatewaybiz.channel.wxpay.wxconfig.WXPayConfigDefine;
import com.oraro.paygatewaybiz.exception.RRException;
import com.oraro.paygatewaybiz.module.entity.ChannelEntity;
import com.oraro.paygatewaybiz.module.entity.OrderEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: jianghuiyong
 * @Date: 2018/11/30 9:31
 * @Version 1.0
 */




@Slf4j
public abstract class AbstractWXBaseService {

    @Value("${notify_url.wxpay}")
    private String notifyUrl;
    @Autowired
    private BizLoggerHelper bizLoggerHelper;

    /**
     * 获取微信下单参数
     * @param orderEntity
     * @return
     */
    protected Map<String, String> getWXRequestData (OrderEntity orderEntity) {
        Map<String, String> map = new HashMap<>();
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        map.put("body", orderEntity.getBody());
        map.put("attach", orderEntity.getOrderId().toString());
        map.put("out_trade_no", orderEntity.getOutTradeNo());
        map.put("total_fee", orderEntity.getTotalFee().toString());
        map.put("trade_type", orderEntity.getTradeType());
        map.put("notify_url", notifyUrl);
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            throw new RRException("获取当前ip失败");
        }
        String spbillCreateIp = addr.getHostAddress();
        map.put("spbill_create_ip", spbillCreateIp);
        return map;
    }

    /**
     * 获取微信下单实例
     * @param channelEntity
     * @return
     */
    protected WXPay getWXPayInstance (ChannelEntity channelEntity) {
        WXPayConfigDefine wxPayConfigDefine = new WXPayConfigDefine(channelEntity.getAppId(), channelEntity.getWxMchId(), channelEntity.getWxMchSecret());
        WXPay wxPay;
        try {
            wxPay = new WXPay(wxPayConfigDefine);
        } catch (Exception e) {
            throw new RRException(e.getMessage());
        }
        return wxPay;
    }

    /**
     * JSAPI,APP统一下单
     * @param map
     * @param channelEntity
     * @return
     */
    protected Result unifiedOrder(Map<String, String> map, ChannelEntity channelEntity) {
        Map<String, String> resp =null;
        boolean isResponseSignatureValid = false;
        WXPay wxPay = getWXPayInstance(channelEntity);
        try {
            resp = wxPay.unifiedOrder(map);
            bizLoggerHelper.log("微信统一下单返回结果:"+ resp.toString());
            isResponseSignatureValid = wxPay.isResponseSignatureValid(resp);
        } catch (Exception e) {
            bizLoggerHelper.log("微信统一下单失败，订单号:" + map.get("out_trade_no"));
            throw new RRException("微信统一下单失败,订单号:"+ map.get("out_trade_no"));
        }
        if (!isResponseSignatureValid) {
            bizLoggerHelper.log("微信下单返回错误:" + resp.toString());
            throw new RRException("微信下单返回错误");
        }
        checkWXRsp(resp);
        return generateResult(resp, channelEntity.getWxMchSecret());
    }
    /**
     * MAP转XML
     * @param result
     * @return
     */
    protected String createWXxmlResult (Map<String, String> result) {
        String xmlResult = "";
        try {
            xmlResult = WXPayUtil.mapToXml(result);
        } catch (Exception e) {
            log.error(e.toString());
        }
        return xmlResult;
    }

    /**
     * 验证下单结果
     * @param resp
     */
    protected void checkWXRsp (Map<String, String> resp) {
        if ("FAIL".equals(resp.get("return_code"))) {
            throw new RRException(resp.get("return_msg"));
        } else if ("FAIL".equals(resp.get("result_code"))) {
            throw new RRException(resp.get("err_code_des"));
        }
    }

    /**
     * 生成JSAPI返回结果
     * @param result
     * @param signKey
     * @return
     */
    protected Result generateResult (Map<String, String> result, String signKey) {

        Map<String, String> map = new HashMap<>();
        map.put("appId", result.get("appid"));
        map.put("timeStamp", String.valueOf(System.currentTimeMillis()/1000));
        map.put("nonceStr", WXPayUtil.generateNonceStr());
        map.put("package", "prepay_id="+ result.get("prepay_id"));
        map.put("signType", WXPayConstants.HMACSHA256);
        String paySign;
        try {
            paySign = WXPayUtil.generateSignature(map, signKey, WXPayConstants.SignType.HMACSHA256);
        } catch (Exception e) {
            throw new RRException("微信生成paySign失败");
        }
        map.put("paySign", paySign);
        return Result.success().data("data", map);
    }
}
